/**
 * 初始化所有数据模型并建立模型间的关系
 * @param {Sequelize} sequelize - Sequelize实例
 * @returns {Object} 包含所有模型的对象
 */

// 引入各个模型定义文件
const sales_orders = require('./sales_orders');
const customers = require('./customers');
const products = require('./products');
const product_categories = require('./product_categories');
const suppliers = require('./suppliers');
const users = require('./users');
// 引入采购订单相关模型
const purchase_orders = require('./purchase_orders');
const purchase_order_items = require('./purchase_order_items');
// 引入快递公司模型
const courier_companies = require('./courier_companies');
// 引入快递信息模型
const express_info = require('./express_info');
// 引入发货单模型
const delivery_orders = require('./delivery_orders');

/**
 * 初始化模型函数
 * @param {Sequelize} sequelize - Sequelize实例
 * @param {DataTypes} DataTypes - Sequelize数据类型
 * @returns {Object} 包含所有模型的对象
 * 
 * 该函数负责：
 * 1. 初始化各个数据模型
 * 2. 建立模型间的关系（关联）
 * 3. 返回包含所有模型的对象
 */
function initModels(sequelize, DataTypes) {
  // 初始化各个模型
  // 每个模型都是一个Sequelize模型实例，用于数据库操作
  const SalesOrders = sales_orders(sequelize, DataTypes);      // 销售订单模型实例
  const Customers = customers(sequelize, DataTypes);            // 客户模型实例
  const Products = products(sequelize, DataTypes);              // 产品模型实例
  const ProductCategories = product_categories(sequelize, DataTypes); // 产品分类模型实例
  const Suppliers = suppliers(sequelize, DataTypes);            // 供应商模型实例
  const Users = users(sequelize, DataTypes);                    // 用户模型实例
  // 初始化采购订单相关模型
  const PurchaseOrders = purchase_orders(sequelize, DataTypes);
  const PurchaseOrderItems = purchase_order_items(sequelize, DataTypes);
  // 初始化快递公司模型
  const CourierCompanies = courier_companies(sequelize, DataTypes);
  // 初始化快递信息模型
  const ExpressInfo = express_info(sequelize, DataTypes);
  // 初始化发货单模型
  const DeliveryOrders = delivery_orders(sequelize, DataTypes);

  // 定义模型间的关系
  // Sequelize支持多种关联关系：一对一(1:1)、一对多(1:N)、多对多(N:M)
  
  // 销售订单与客户的关系（多对一）
  // 一个客户可以有多个订单，一个订单只属于一个客户
  // SalesOrders.belongsTo(Customers): 建立销售订单到客户的多对一关联
  SalesOrders.belongsTo(Customers, { 
    as: 'customer',       // 关联别名，用于查询时引用
    foreignKey: 'customer_id'  // 外键字段名
  });
  // Customers.hasMany(SalesOrders): 建立客户到销售订单的一对多关联
  Customers.hasMany(SalesOrders, { 
    as: 'sales_orders',   // 关联别名，用于查询时引用
    foreignKey: 'customer_id'  // 外键字段名
  });

  // 销售订单与产品的关系（多对一）
  // 一个产品可以有多个订单记录，一个订单只包含一个产品
  // SalesOrders.belongsTo(Products): 建立销售订单到产品的多对一关联
  SalesOrders.belongsTo(Products, { 
    as: 'product',        // 关联别名，用于查询时引用
    foreignKey: 'product_id'   // 外键字段名
  });
  // Products.hasMany(SalesOrders): 建立产品到销售订单的一对多关联
  Products.hasMany(SalesOrders, { 
    as: 'sales_orders',   // 关联别名，用于查询时引用
    foreignKey: 'product_id'   // 外键字段名
  });

  // 产品与产品分类的关系（多对一）
  // 一个分类可以包含多个产品，一个产品只属于一个分类
  // Products.belongsTo(ProductCategories): 建立产品到产品分类的多对一关联
  Products.belongsTo(ProductCategories, { 
    as: 'category',       // 关联别名，用于查询时引用
    foreignKey: 'category_id'  // 外键字段名
  });
  // ProductCategories.hasMany(Products): 建立产品分类到产品的一对多关联
  ProductCategories.hasMany(Products, { 
    as: 'products',       // 关联别名，用于查询时引用
    foreignKey: 'category_id'  // 外键字段名
  });
  
  // 产品分类自关联（父子分类关系）
  // 一个分类可以有多个子分类，一个子分类只属于一个父分类
  // ProductCategories.belongsTo(ProductCategories): 建立产品分类到自身的多对一关联（自关联）
  ProductCategories.belongsTo(ProductCategories, {
    as: 'parent',         // 父分类关联别名
    foreignKey: 'parent_id'    // 父分类外键字段名
  });
  // ProductCategories.hasMany(ProductCategories): 建立产品分类到自身的自关联
  ProductCategories.hasMany(ProductCategories, {
    as: 'children',       // 子分类关联别名
    foreignKey: 'parent_id'    // 父分类外键字段名
  });

  // 产品与供应商的关系（多对一）
  // 一个供应商可以提供多个产品，一个产品只属于一个供应商
  // Products.belongsTo(Suppliers): 建立产品到供应商的多对一关联
  Products.belongsTo(Suppliers, { 
    as: 'supplier',       // 关联别名，用于查询时引用
    foreignKey: 'supplier_id'  // 外键字段名
  });
  // Suppliers.hasMany(Products): 建立供应商到产品的一对多关联
  Suppliers.hasMany(Products, { 
    as: 'products',       // 关联别名，用于查询时引用
    foreignKey: 'supplier_id'  // 外键字段名
  });
  
  // 采购订单与供应商的关系（多对一）
  PurchaseOrders.belongsTo(Suppliers, { 
    as: 'supplier', 
    foreignKey: 'supplier_id' 
  });
  Suppliers.hasMany(PurchaseOrders, { 
    as: 'purchase_orders', 
    foreignKey: 'supplier_id' 
  });
  
  // 采购订单项与采购订单的关系（多对一）
  PurchaseOrderItems.belongsTo(PurchaseOrders, { 
    as: 'purchase_order', 
    foreignKey: 'po_id' 
  });
  PurchaseOrders.hasMany(PurchaseOrderItems, { 
    as: 'purchase_order_items', 
    foreignKey: 'po_id' 
  });
  
  // 采购订单项与产品的关系（多对一）
  PurchaseOrderItems.belongsTo(Products, { 
    as: 'product', 
    foreignKey: 'product_id' 
  });
  Products.hasMany(PurchaseOrderItems, { 
    as: 'purchase_order_items', 
    foreignKey: 'product_id' 
  });
  
  // 销售订单与快递信息的多对一关系
  // 多个订单可以对应一个快递信息
  SalesOrders.belongsTo(ExpressInfo, {
    as: 'express_info',
    foreignKey: 'express_id'
  });
  ExpressInfo.hasMany(SalesOrders, {
    as: 'sales_orders',
    foreignKey: 'express_id'
  });
  
  // 出库记录与订单的一对多关系
  // 一个出库记录可以包含多个订单
  // OrderOutbounds.hasMany(SalesOrders, {
  //   as: 'orders',
  //   foreignKey: 'outbound_id'
  // });
  // SalesOrders.belongsTo(OrderOutbounds, {
  //   as: 'outbound',
  //   foreignKey: 'outbound_id'
  // });

  // 发货单与快递公司的关系
  DeliveryOrders.belongsTo(CourierCompanies, {
    as: 'courier',
    foreignKey: 'courier_id'
  });
  CourierCompanies.hasMany(DeliveryOrders, {
    as: 'delivery_orders',
    foreignKey: 'courier_id'
  });

  // 发货单与销售订单的关系（一对多）
  // 一个发货单可以包含多个订单
  DeliveryOrders.hasMany(SalesOrders, {
    as: 'sales_orders',
    foreignKey: 'delivery_id'
  });
  SalesOrders.belongsTo(DeliveryOrders, {
    as: 'delivery_order',
    foreignKey: 'delivery_id'
  });

  // 返回包含所有模型的对象
  // 便于在其他模块中通过解构赋值的方式引入所需模型
  return {
    sales_orders: SalesOrders,
    customers: Customers,
    products: Products,
    product_categories: ProductCategories,
    suppliers: Suppliers,
    users: Users,
    purchase_orders: PurchaseOrders,
    purchase_order_items: PurchaseOrderItems,
    courier_companies: CourierCompanies,
    express_info: ExpressInfo,
    delivery_orders: DeliveryOrders
  };
}

// 导出初始化函数
// 供其他模块调用以获取初始化后的模型
module.exports = initModels;